
package com.rem.shiro.config;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.rem.shiro.mapper.PermsMapper;
import com.rem.shiro.mapper.RoleMapper;
import com.rem.shiro.mapper.RolePermsMapper;
import com.rem.shiro.mapper.UserMapper;
import com.rem.shiro.mapper.UserRoleMapper;
import com.rem.shiro.pojo.Perms;
import com.rem.shiro.pojo.Role;
import com.rem.shiro.pojo.RolePerms;
import com.rem.shiro.pojo.User;
import com.rem.shiro.pojo.UserRole;
import com.rem.shiro.utils.ApplicationContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.stream.Collectors;


/**
 * @author Rem
 * @date 2021-04-06
 */


@Slf4j
public class ShiroRealm extends AuthorizingRealm {

    @Autowired
    UserMapper userMapper;
    @Autowired
    UserRoleMapper userRoleMapper;
    @Autowired
    RoleMapper roleMapper;


    /**
     * 授权
     *
     * @param principals
     * @return
     */


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        //获取身份信息
        String primaryPrincipal = (String) principals.getPrimaryPrincipal();
        System.out.println("调用授权验证:" + primaryPrincipal);
        //获取角色和权限信息
        if ("zhangsan".equals(primaryPrincipal)) {
            //获取角色名称
            User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, primaryPrincipal));
            List<UserRole> userRoles = userRoleMapper.selectList(new LambdaQueryWrapper<UserRole>().eq(UserRole::getUserId, user.getId()));
            List<Integer> roleIds = userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toList());
            List<Role> roleList = roleMapper.selectList(new LambdaQueryWrapper<Role>().in(Role::getId, roleIds));
            List<String> roleNames = roleList.stream().map(Role::getName).collect(Collectors.toList());

            //获取权限信息
            RolePermsMapper rolePermsMapper = (RolePermsMapper) ApplicationContextUtils.getBean("rolePermsMapper");
            PermsMapper permsMapper = (PermsMapper) ApplicationContextUtils.getBean("permsMapper");

            List<RolePerms> rolePerms = rolePermsMapper.selectList(new LambdaQueryWrapper<RolePerms>().in(RolePerms::getRoleId, roleIds));
            List<Integer> permsIds = rolePerms.stream().map(RolePerms::getPermsId).collect(Collectors.toList());
            List<Perms> permsList = permsMapper.selectList(new LambdaQueryWrapper<Perms>().in(Perms::getId, permsIds));
            List<String> permsNames = permsList.stream().map(Perms::getName).collect(Collectors.toList());

            SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
            simpleAuthorizationInfo.addRoles(roleNames);
            simpleAuthorizationInfo.addStringPermissions(permsNames);
            return simpleAuthorizationInfo;
        }
        return null;
    }


    /**
     * 认证
     *
     * @param token
     * @return
     * @throws AuthenticationException
     */


    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
        log.debug("username:" + username);
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));

        if (user != null) {
            return new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), this.getName());
        }
        return null;
    }
}

